package com.liyunc.demo.annotation;


import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解.
 * 防止表单重复提交注解，保证幂等性
 * 幂等性，通俗的说就是一个接口，多次发起一个请求，必须保证操作只能执行一次
 * 比如：
 * 1.订单接口，不能多次创建订单
 * 2.支付接口，重复支付同一笔订单只能扣一次钱
 * 3.支付宝回调接口，可能会多次回调，必须处理重复回调
 * 4.普通表单提交接口，因为网络超时等原因多次点击提交，只能成功一次
 * ...
 * 常见解决方法：
 * 1.唯一索引--防止新增脏数据
 * 2.token机制--防止页面重复提交
 * 3.悲观锁--获取数据的时候加锁（锁表或锁行）
 * 4.乐观锁--基于版本号version实现，在更新数据那一刻校验数据
 * 5.分布式锁--redis（jedis、redisson）或zookeeper实现
 * 6.状态机--状态变更，更新数据时判断状态
 * ...
 * 原理：AOP+Token防止表单重复提交
 * 思路：在表单提交前先请求后台获取token，后台随机生成token保存在session中，提交表单时在请求参数
 * 中带上获取的token即可，后台从session中校验token是否匹配
 * 1.如果存在token，正常处理业务逻辑，并从session中删除此token，那么如果时重复请求，由于
 * token已被删除，则不能通过校验，返回请勿重复操作提示
 * 2.如果不存在，说明参数不合法或者时重复请求，返回提示
 */

@Documented
//作用到方法上
@Target(ElementType.METHOD)
//运行时有效
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmitToken {
    /**
     * 保存重复提交标记，默认为不需要保存
     */
    boolean save() default false;

    /**
     * 默认删除为false
     */
    boolean remove() default false;

}
